package cn.slipi.core.filter.concrete;

import cn.slipi.common.constants.Constants;
import cn.slipi.common.entity.RequestLog;
import cn.slipi.common.rule.custom.entity.MatchCondition;
import cn.slipi.core.filter.AbstractFilter;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;

import java.util.Objects;

/**
 * ParamVerifyFilter
 */
public class ParamVerifyFilter extends AbstractFilter {

    @Override
    protected Mono<Boolean> doFilter(ServerWebExchange exchange, WebFilterChain chain) {
        final ServerHttpRequest request = exchange.getRequest();
        MatchCondition requestMatchCondition = MatchCondition.transform(request);
        if (verify(requestMatchCondition)) {

            RequestLog requestLog = new RequestLog();
            requestLog.setAppKey(requestMatchCondition.getAppKey());
            requestLog.setApiCode(requestMatchCondition.getApiCode());
            requestLog.setStartTimestamp(System.currentTimeMillis());
            requestLog.setHeader(JSONObject.toJSONString(request.getHeaders()));
            exchange.getAttributes().put(Constants.REQUEST_LOG, requestLog);

            exchange.getAttributes().put(Constants.GATEWAY_HEADER, requestMatchCondition);
        } else {
            return Mono.just(false);
        }
        return Mono.just(true);
    }

    private boolean verify(MatchCondition requestMatchCondition) {
        return !Objects.isNull(requestMatchCondition) && !StringUtils.isBlank(requestMatchCondition.getQueryType()) && !StringUtils.isBlank(requestMatchCondition.getApiCode());
    }

    @Override
    protected Mono<Void> doDenyResponse(ServerWebExchange exchange) {
        ServerHttpResponse response = exchange.getResponse();
        response.setStatusCode(HttpStatus.BAD_REQUEST);
        return response.writeWith(Mono.just(response.bufferFactory().wrap(JSON.toJSONString(HttpStatus.BAD_REQUEST.getReasonPhrase()).getBytes())));
    }
}
